//------------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from ARM Limited.
//
//            (C) COPYRIGHT 2008-2012 ARM Limited.
//                ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from ARM Limited.
//------------------------------------------------------------------------------
// Version and Release Control Information:
//
// File Revision       : 127275
// File Date           :  2012-03-19 15:37:15 +0000 (Mon, 19 Mar 2012)
// Release Information : PL401-r0p1-00eac0
//------------------------------------------------------------------------------
//  Purpose : This is a cdc corruption block.
//            It is a non-functional verification block that (when enabled)
//            corrupts the any bit of the data for the next two clock edges.
//            after any change. It is intended to help prove that handshake 
//            mechanisms surrounding the data are all working as expected.
// ----------------------------------------------------------------------------

module nic400_ib_chiplink_slv_axi4_tpv_ib_cdc_air_corrupt_ysyx_rv32 (
  d,
  q
  );

  parameter WIDTH = 1;
  parameter DIRECTION = "fwd";
  
  // ------------------------------------------------------
  // port declaration
  // ------------------------------------------------------
  input  [WIDTH-1:0]  d;
  output [WIDTH-1:0]  q;

  // -------------------------------------------
  // reg/wire declarations
  // ------------------------------------------------------

`ifdef ARM_CDC_CHECK

  wire                  change;
  reg      [WIDTH-1:0]  d_latch;
  wire     [WIDTH-1:0]  out;
  wire     clk;
  wire     async;
  reg      p1;
  reg      p2;

  `ifdef ARM_CDC_BLOCK_LEVEL
  
      //Get the async for this block
      assign async = 1'b1;

      //Get the clk for this block
      assign clk   = (DIRECTION == "fwd") ? u_DUT.clk_peri_25mclk
                                          : u_DUT.clk_core_200_800mclk;

  `else

      //Get the async for this block
      assign async = 1'b1;


      //Get the clk for this block
      assign clk   = (DIRECTION == "fwd") ? nic400_ysyx_rv32.clk_peri_25mclk
                                          : nic400_ysyx_rv32.clk_core_200_800mclk;

  `endif


  //Set the appropriate output based on async
  assign q = (async) ? out : d;

  //Latch to detect change on incoming data 
  always @(d)
     d_latch <= d;

  //Create delta cycle pulse to reset pipeline on change
  assign change = (d !== d_latch);   

  //Pipeline is reset to 1s on any change in data
  //Data should be corrupted until the pipeline is clear
  always @(posedge clk or posedge change)
    begin 
       if (change) begin
          p1 <= 1'b1;
          p2 <= 1'b1;
       end else begin
          p1 <= 1'b0;
          p2 <= p1;
       end
    end

  //Corrupt data while there is something in the pipeline 
  assign out = (p2) ? {WIDTH{1'bz}} : d;

`else

  assign q = d;

`endif
  
endmodule
